package drds.binlog;

import java.io.Closeable;
import java.io.IOException;
import java.util.Arrays;

/**
 * Declaration a binary-log fetcher. It extends from <code>LogByteBlock</code>.
 * <p>
 * <pre>
 * LogFetcher fetcher = new SomeLogFetcher();
 * ...
 *
 * while (fetcher.fetch())
 * {
 *     LogEvent event;
 *     do
 *     {
 *         event = decoder.decode(fetcher, context);
 *
 *         // process log event.
 *     }
 *     while (event != null);
 * }
 * // no more binlog.
 * fetcher.close();
 * </pre>
 */
public abstract class LogFetcher extends LogByteBlock implements Closeable
{

    /**
     * Default initial capacity.
     */
    public static final int default_initial_capacity = 8192;

    /**
     * Default growth factor.
     */
    public static final float default_growth_factor = 2.0f;

    /**
     * Binlog file headerPacket size
     */
    public static final int bin_log_header_size = 4;

    protected final float factor;

    public LogFetcher()
    {
        this(default_initial_capacity, default_growth_factor);
    }

    public LogFetcher(final int initialCapacity)
    {
        this(initialCapacity, default_growth_factor);
    }

    public LogFetcher(final int initialCapacity, final float growthFactor)
    {
        this.bytes = new byte[initialCapacity];
        this.factor = growthFactor;
    }

    /**
     * Increases the capacity of this <tt>LogFetcher</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param capacity the desired minimum capacity
     */
    protected final void ensureCapacity(final int capacity)
    {
        final int length = bytes.length;

        if (capacity > length)
        {
            int newCapacity = (int) (length * factor);
            //max
            if (newCapacity < capacity)
            {
                newCapacity = capacity;
            }
            bytes = Arrays.copyOf(bytes, newCapacity);
        }
    }

    /**
     * Fetches the next frame of binary-log, and fill it in bytes.
     */
    public abstract boolean fetch() throws IOException;

    public abstract void close() throws IOException;
}
